<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>对ajax进行总结</title>
</head>
<body>
<!--
   script 标签的特点是
   1. innerHTML 永远不会显示在界面上
   2. 如果 type 不等于 text/javascript 的话，内部的内容不会作为 JavaScript 执行
 -->
<script type="application/javascript">
	var url = '../testAjax';
	//涉及到AJAX操作的页面“不能”使用文件协议访问（文件的方式访问）

	//AJAX是一套API核心提供的类型：XMLHttpRequest
	//1.安装浏览器（用户代理）
	//xhr就类似于浏览器的作用（发送请求接收响应）
    var xhr = new XMLHttpRequest();
    //2.打开浏览器，输入网址
    console.log("初始化，请求代理对象,new XMLHttpRequest响应的状态="+xhr.readyState);
    //==>0 初始化，请求代理对象
    //xhr.open('GET',url);
    // open 方法的第三个参数是 async 可以传入一个布尔值，默认为 true
    xhr.open('POST',url,true);
    xhr.setRequestHeader('Foo','Bar');//设置一个请求头
    // 一旦你的请求体是 urlencoded 格式的内容，一定要设置请求头中 Content-Type 'application/x-www-form-urlencoded'
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');


    console.log("open方法已经调用，建立一个服务端特定端口的连接，响应的状态="+xhr.readyState);
   	//3.敲回车键，开始请求
   	xhr.send('key1=value1&key2=value2');//以urlencoded 格式设置请求体
   	//因为客户端永远不知道服务端何时才能返回我们需要的响应
   	//所以AJAX API采用事件的机制（通知的感觉）
   	// xhr.onreadystatechange = function(){
   	// 	//这个事件并不是只在响应时触发，XHR状态改变就触发
   	// 	console.log("响应状态="+this.readyState);
   	// 	if(this.readyState != 4)
   	// 		return;
   	// 	//获取相应的内容（响应体)
   	// 	console.log(this.responseText);
   	// }
    // 我们通过代码告诉请求代理对象，服务端响应给我们的是 JSON
    xhr.responseType = 'json'
   	xhr.addEventListener("readystatechange",function(){
   	    switch (this.readyState){
            case 2:
                    console.log("已经接受到响应报文的响应头，响应状态为="+this.readyState);
                    console.log("响应头为="+this.getAllResponseHeaders());
                    console.log("====="+this.getResponseHeader('server'));
            //但是还没有拿到返回体
            case 3:
                    console.log("正在下载相应报文的响应体，有可能响应体为空，也有可能不完整，这里处理相应体不保险");
                    console.log("相应体为="+this.responseText);
            case 4:
                    console.log("整个响应报文已经完整下载下来了，响应状态为="+this.readyState+";响应体内容为= +"+this.responseText);
                // this.responseXML 专门用于获取服务端返回的 XML 数据，操作方式就是通过 DOM 的方式操作
                // 但是需要服务端响应头中的 Content-Type 必须是 application/xml
                // console.log(this.responseXML.documentElement.children[0].innerHTML)
                // console.log(this.responseXML.documentElement.getElementsByTagName('name')[0])
                // this.response 获取到的结果会根据 this.responseType 的变化而变化
                // this.responseText 永远获取的是字符串形式的响应体
        }

    })
    //onload 是HTML5中提供的XMLHTTpRequest V2.0定义的
    xhr.onload = function(){
        console.log("响应状态="+this.readyState);
        console.log("响应的返回体"+this.responseText);
    }

</script>

<script type="application/javascript">
    // 封装者
    // =============================

    function ajax (method, url, params, done) {
        method = method.toUpperCase()
        var xhr = new XMLHttpRequest()

        if (typeof params === 'object') {
            var tempArr = []
            for (var key in params) {
                var value = params[key]
                tempArr.push(key + '=' + value)
            }
            params = tempArr.join('&')
        }

        if (method === 'GET') {
            url += '?' + params
        }

        xhr.open(method, url, false)

        var data = null
        if (method === 'POST') {
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
            data = params
        }

        xhr.onreadystatechange = function () {
            if (this.readyState !== 4) return
            // 不应该在封装的函数中主观的处理响应结果
            // console.log(this.responseText)
            // 你说我太主观，那么你告诉我应该做什么
            done(this.responseText)
        }

        xhr.send(data)
    }

    // 调用者
    // ============================

    var onDone = function (res) {
        console.log('hahahahaha')
        console.log('hohohohoho')
        console.log(res)
        console.log('做完了')
    }

   // ajax('get', 'time.php', {}, onDone)


</script>

<!-- <img src="http://ww1.sinaimg.cn/large/006ThXL5ly1fj8w5i2onyj302u02umwz.jpg" alt=""> -->
<script>
    //跨域问题解决原理
    // 请求一个不同源的地址实际上就是我们所说的跨域请求

    // 当前页面访问地址：http://day-12.io/12-cross-origin.html
    // 希望被请求的地址：http://locally.uieee.com/categories
    //
    // 校验目标：1 能发出去，2 能收回来

    // img link script iframe
    //
    // ## 1. img
    // 可以发送不同源地址之间的请求
    // 无法拿到响应结果
    // var img = new Image()
    // img.src = 'http://locally.uieee.com/categories'

    // ## 2. link
    // 可以发送不同源地址之间的请求
    // 无法拿到响应结果
    // var link = document.createElement('link')
    // link.rel = 'stylesheet'
    // link.href = 'http://locally.uieee.com/categories'
    // document.body.appendChild(link)

    // ## 3. script
    // 可以发送不同源地址之间的请求
    // 无法拿到响应结果
    // 借助于能够作为 JS 执行
    var script = document.createElement('script')
    script.src = 'http://localhost/time2.php'
    document.body.appendChild(script) // 开始发起请求
    // 相当于请求的回调
    function foo (res) {
        console.log(res)
    }
    // console.log(a) 并且后台需要变成
    // JSON with Padding，是一种借助于 script 标签发送跨域请求的技巧。
    // 其原理就是在客户端借助 script 标签请求服务端的一个动态网页（php 文件），服务端的这个动态网页返回一
    // 段带有函数调用的 JavaScript 全局函数调用的脚本，将原本需要返回给客户端的数据传递进去。
    // 以后绝大多数情况都是采用 JSONP 的手段完成不同源地址之间的跨域请求

    $.ajax({
        url: 'http://localhost/jsonp/server.php',
        dataType: 'jsonp',
        success: function (res) {
            console.log(res)
        }
    })
</script>
</body>
</html>